/***************************************************************************************** 
*                                     TinyRtos51 
*                                The Real-Time Kernel 
*                              Copyright(c) 2024 fanxsp
*                         SPDX-License-Identifier: APACHE-2.0
*       This software is subject to an open source license and is distributed by fanxsp,
*       pursuant to the terms of the Apache License.
******************************************************************************************/
/***************************************************************************************** 
* 				TinyRtos51 头文件
* Author: fanxsp 
* Revision: 1.00
* Date: 2023-05-03
* Revision: 1.10
* Date: 2024-04-07
*	增加reentrant函数支持
* Revision: 1.20
* Date：2024-04-20
*	1. 新增在任务中挂起其它任务(可裁剪)
*   2. 新增动态优先级支持(可裁剪)
*	3. 修正一个链表操作的错误(会造成多个任务等待同一事件时，系统崩溃)
******************************************************************************************/
#ifndef __TINY_RTOS51_H 
#define __TINY_RTOS51_H

/* 版本号定义  */                                                      
#define OSVER_MAJOR             1
#define OSVER_MINOR             0
#define OSVER_SUBMINOR          0
                                
#define OSVERSION               ( OSVER_MAJOR*100 \
                                + OSVER_MINOR*10  \
                                + OSVER_SUBMINOR )
#define OSVersion()             OSVERSION      

/* 数据类型定义  */
typedef __bit         OStypeBool;      // FALSE or TRUE       
typedef signed char   OStypeInt8;      // -128 to +127        
typedef unsigned char OStypeInt8u;     // 0 to +255           
typedef signed int    OStypeInt16;     // -32768 to +32767    
typedef unsigned int  OStypeInt16u;    // 0 to +65,535        
typedef signed long   OStypeInt32;     // -2.1B to +2.1B      
typedef unsigned long OStypeInt32u;    // 0 to +4,294,967,295 

//typedef void(code * OStypeTFP)(void) ;   // 任务函数指针
typedef void (* OStypeTFP)( void * arg );

/* 配置选项 */
/* 编译器  */     
// #define OSKEIL_C51              1      // Keil C51            
/* Keil Cx51 compiler */
#if defined(__C51__) || defined(__CX51__)
#define OSCOMPILER    OSKEIL_C51
#endif 

/* 配置文件 */
#include "tinyrtos51cfg.h"

/* 配置选项默认值  */
/* 任务延时计数器类型  */
#if OSBYTES_OF_DELAYS > 1
#define OStypeOfDelays  OStypeInt16u
#else 
#define OStypeOfDelays OStypeInt8u 
#endif

/* 空闲任务堆栈长度  */
#define OSIDLE_STACKS  3   

/* 内核变量存储位置  */
#define OSLOC_CORE __data  

/* 移植文件port.h，包含编译器、处理器相关的配置 */
#include "port.h"

/* List 结构  */
typedef struct
{
	OStypeInt8u next ;  // 下一个结点
	OStypeInt8u prev ;  // 上一个结点
} OStypeList ;

/* 任务控制块结构：     */                                                   
typedef struct 
{
	OStypeInt8u state:   2 ;    // 任务状态 0-就绪 1-挂起 2-延时 3-等待事件
	OStypeInt8u prio:    4 ;    // 任务优先级: 0-15 0为最高优先级,15为最低优先级 15-空闲任务使 0-14用户任务使用
	OStypeInt8u pree:    1 ;    // 0-非抢先(不恢复寄存器)  1-抢先(恢复寄存器)
	OStypeInt8u timeout: 1 ;    // 超时标志
	OStypeInt8u OSLOC_STACKS * stackBottom ;   // 任务栈底
	OStypeInt8u stackSize ;     // 任务堆栈中的数据个数 =0 任务未初始化
#if OSENABLE_REENTRANT_SMALL > 0
	OStypeInt8u OSLOC_STACKS* smallStackBottom ; // small reentrant栈底
	OStypeInt8u smallStackSize ; // small reentrant 栈的数据个数
#endif
#if OSENABLE_REENTRANT_LARGE > 0
	OStypeInt8u OSLOC_STACKS* largeStackTop ; // large reentrant栈顶
#endif
#if OSENABLE_SETPRIO > 0
	OStypeInt8u inList ; // TCB所在的列表 0-不在任何列表中
#endif
#if OSBYTES_OF_DELAYS > 0
	OStypeOfDelays delay ;      // 延时计数器
#endif
} OStypeTcb;   

/* 消息队列 ECB 结构  */
typedef struct
{
	OStypeInt8u rear ;     // 队尾   
	OStypeInt8u front ;    // 队头
	OStypeInt8u size ;     // 队列长度
	OStypeInt8u count ;    // 消息个数
	OStypeInt8u OSLOC_MSGQ_BUF * buf ;  // 缓冲区指针
} OStypeMsgQ ;                 
 
/* 常量定义  */
/* 任务优先级:0-最高优先级，14-任务最低优先级，15空闲任务优先级 */
#define OSHI_PRIO                  0
#define OSLOW_PRIO                 15

/* 任务状态*/
#define OSTCB_ELIGIBLE     0   // 就绪
#define OSTCB_SUSPENDED    1   // 挂起   
#define OSTCB_DELAYING     2   // 延时   
#define OSTCB_WAITING      3   // 等待事件                                    

/* 错误代码 */
#define OSNOERR                    0
#define OSERR                      1

/* 内核 API / 全局变量  */
#ifdef __IN_OSCORE_C
#define OSCORE_EXT
#else
#define OSCORE_EXT extern
#endif

#ifdef __IN_OSCORE_ASM_C
#define OSCORE_ASM_EXT
#else
#define OSCORE_ASM_EXT extern
#endif

/* OSCore.c中定义的全局变量  */
OSCORE_EXT OStypeInt8u OSLOC_CORE OSEnterSum ;    // 临界区进入深度
OSCORE_EXT OStypeInt8u OSLOC_CORE OSTaskRunning ; // 当前运行任务ID
OSCORE_EXT OStypeInt8u OSLOC_CORE OSTaskNext ;    //即将运行的任务ID
OSCORE_EXT OStypeInt8u OSLOC_CORE OSStack ;       // 内部栈底
#if OSENABLE_REENTRANT_LARGE > 0
OSCORE_EXT OStypeInt16u OSLOC_CORE OSLargeStack ;  // 内部large reentrant栈底
OSCORE_EXT OStypeInt8u OSLOC_CORE OSNesting ;      // 中断嵌套跟踪
OSCORE_EXT OStypeInt16u OSLOC_CORE OSXBPSave ;     // 保存任务级的XBP
OSCORE_EXT OStypeInt16u OSLOC_CORE OSTmp16u ;      // 内核使用的临时变量
#endif

OSCORE_EXT OStypeList OSLOC_LIST OSListArea[OSTASKS+1+OSBINSEMS+OSSEMS
	+OSEFLAGS+OSMSGQS] ;                                // List数组
OSCORE_EXT OStypeTcb OSLOC_TCB  OSTcbArea[OSTASKS+1] ;  // 任务控制块数组

/* 链表头指针  */
#define OSHeadEligible  OSTASKS                                    // 就绪表头指针
#define OSHeadBinSem(eID) (OSTASKS+1+eID)                          // BinSem等待列表头指针
#define OSHeadSem(eID) (OSTASKS+1+OSBINSEMS+eID)                   // BinSem等待列表头指针
#define OSHeadEFlag(eID) (OSTASKS+1+OSBINSEMS+OSSEMS+eID)          // EFlag等待列表头指针
#define OSHeadMsgQ(eID) (OSTASKS+1+OSBINSEMS+OSSEMS+OSEFLAGS+eID)  // MsgQ等待列表头指针

/* 空闲任务ID */
#define OSTCBIDLE   OSTASKS

/* 内核初始化  */
OSCORE_EXT void OSInit(void) ;

/************************************************************************************************* 
* TCB按优先级升序添加到就绪表或等待列表任务到就绪表或等待列表
* 参数：listHead List头指针
*       tID 任务ID
**************************************************************************************************/
OSCORE_EXT void OSAppendToList(OStypeInt8u listHead,OStypeInt8u tID) ;

/*************************************************************************************************
* 创建任务
* 参数：tID -任务ID  fp -任务函数指针 stack -任务堆栈指针 prio -任务优先级
*      stackSize -堆栈总长度  largeStackSize -large reentrant堆栈长度 
**************************************************************************************************/
#if OSENABLE_REENTRANT_SMALL > 0
OSCORE_EXT void OSCreateTask(OStypeInt8u tID,OStypeTFP fp,OStypeInt8u OSLOC_STACKS* stack,
	OStypeInt8u stackSize,OStypeInt8u largeStackSize,OStypeInt8u prio) ;
#elif OSENABLE_REENTRANT_LARGE >0
OSCORE_EXT void OSCreateTask(OStypeInt8u tID,OStypeTFP fp,OStypeInt8u OSLOC_STACKS* stack,
	OStypeInt8u stackSize,OStypeInt8u prio) ;
#else
OSCORE_EXT void OSCreateTask(
	OStypeInt8u tID,	// 任务ID
	OStypeTFP fp,		// 任务执行函数指针
	OStypeInt8u OSLOC_STACKS * stack,	// 给任务分配的堆栈
	OStypeInt8u prio) ;					// 任务的优先级
#endif

/************************************************************************************************* 
* 从就绪表或等待列中删除任务 必须确保任务在列表中 
* 参数：tID 任务ID
**************************************************************************************************/
OSCORE_EXT void OSDelFromList(OStypeInt8u tID) ;

/************************************************************************************************* 
* 宏：查找就绪表或等待列表中最高优先级任务  
* 参数：listHead 就绪表或等待列表表头指针
*************************************************************************************************/
#define OSHiPrioInList(listHead) (OSListArea[listHead].prev)

/* 任务级任务切换  */
OSCORE_EXT void OSSched(void)  ;

/**************************************************************************************************** 
* 在任务中挂起任务 
* 不支持在中断挂起任务，因为在中断中挂起当前任务有可能导致意外的后果。原因分析如下：在中断中挂起当
* 前任务时，会将当前任务的TCB从就绪表中删除，由于是采用模拟pendSV中断来切换任务，程序必须先返回当前
* 任务，然后响应模拟pendSV中断进行任务切换，由于中断响应的时序回题，当前任务有可能先运行一段程序后才
* 响应pendSV中断，如当前任务在这段程序中操作就绪表，就会导致不可预知的意外后果。虽然在中断中挂起其它
* 任务，不会导致这个问题，为了避免意外，不支持在中断挂起任务。                  
*****************************************************************************************************/
#if OSENABLE_SUSPENDID > 0
OSCORE_EXT void OSTaskSuspendID(OStypeInt8u tID) ;      // 任务中挂起指定任务 只在任务级调用
#define OSTaskSuspend() OSTaskSuspendID(OSTaskRunning)  // 任务中挂起当前任务 只在任务级调用
#else
OSCORE_EXT void OSTaskSuspend(void) ;                   // 任务中挂起当前任务 只在任务级调用
#endif

/*************************************************************************************************
* 中断中恢复挂起的任务
* 参数：tID: 任务ID
**************************************************************************************************/
OSCORE_EXT void OSIntResume(OStypeInt8u tID) ;

/*************************************************************************************************
* 任务级恢复挂起的任务
* 参数：tID: 任务ID
*************************************************************************************************/
OSCORE_EXT void OSTaskResume(OStypeInt8u tID) ;

/************************************************************************************************
* 恢复挂起的任务 不含进/出临界区 不能直接调用
* 参数：tID: 任务ID
*************************************************************************************************/
OSCORE_EXT void OSResume(OStypeInt8u tID) ;

/************************************************************************************************* 
* 超时检测 
* 返回值：1 超时   0 未超时
**************************************************************************************************/
OSCORE_EXT OStypeInt8u OSTimeOut(void) ;

/*************************************************************************************************
* 查询任务状态
* 参数：tID: 任务ID 
* 返回值：0(OSTCB_ELIGIBLE)-就绪 1(OSTCB_SUSPENDED)-挂起 2(OSTCB_DELAYING)-延时 3(OSTCB_WAITING)-等待事件   
*************************************************************************************************/
OSCORE_EXT OStypeInt8u OSTaskStateQuery(OStypeInt8u tID) ;

/************************************************************************************************
* 查询任务优先级
* 参数：tID: 任务ID 
* 返回值：任务优先级   
*************************************************************************************************/
OSCORE_EXT OStypeInt8u OSTaskPrioQuery(OStypeInt8u tID) ;

/* 节拍处理  */
OSCORE_EXT void OSTimeTick() ;

/*************************************************************************************************
* 任务延时   
* 参数：ticks 延时节拍数                    
*************************************************************************************************/
#if OSBYTES_OF_DELAYS > 0
OSCORE_EXT void OSDelay(OStypeOfDelays ticks) ;
#endif

#if OSENABLE_SETPRIO > 0
/*************************************************************************************************
* 任务中设置指定任务的优先级   
* 参数：tID: 任务ID  prio : 任务优先级                    
*************************************************************************************************/
OSCORE_EXT void OSTaskSetPrio(OStypeInt8u tID,OStypeInt8u prio) ;

/*************************************************************************************************
* 中断中设置指定任务的优先级   
* 参数：tID: 任务ID  prio : 任务优先级                    
*************************************************************************************************/
OSCORE_EXT void OSIntSetPrio(OStypeInt8u tID,OStypeInt8u prio) ;

/************************************************************************************************
* 设置指定任务的优先级 不含进/出临界区 不能直接调用
* 参数：tID: 任务ID  prio : 任务优先级
*************************************************************************************************/
OSCORE_EXT void OSSetPrio(OStypeInt8u tID,OStypeInt8u prio) ;
#endif

/* 启动内核  */
OSCORE_ASM_EXT void OSStart(void) ; 

/* 任务级任务切换 不含开/关中断 不能在用户程序中直接调用 直接调用使用 OSSched() */
OSCORE_ASM_EXT void OSTaskSw(void) ;

/* 中断级任务调度 在PendSV中断中调用  */
OSCORE_ASM_EXT void OSIntTaskSw(void) ;

/* 任务上下文切换   */
OSCORE_ASM_EXT void OSCtxSw(void) ;

/* 中断嵌套跟踪 切换large reentrant 栈 */
OSCORE_ASM_EXT void OSEnterInt(void) ;
OSCORE_ASM_EXT void OSExitInt(void) ;

/* 二进制信号量 BinSem  */
#ifdef __IN_OSBINSEM_C
#define OSBINSEM_EXT
#else
#define OSBINSEM_EXT extern
#endif

/* 宏 位操作   */
#define OSBinSemSet(eID) (OSBinSemArea[eID/8] |= OSBinSemMask[eID & 0xf8])
#define OSBinSemClr(eID) (OSBinSemArea[eID/8] &= ~OSBinSemMask[eID & 0xf8])
#define OSBinSemGet(eID) (OSBinSemArea[eID/8] & OSBinSemMask[eID & 0xf8])

/* API  */
/************************************************************************************************
* 初始化二进制信号量  在OSStart() 前调用
* 参数：eID  二进制信号量ID   state 状态
************************************************************************************************/
OSBINSEM_EXT void OSInitBinSem(OStypeInt8u eID,OStypeInt8u state) ;

/***********************************************************************************************
* 等待二进制信号量 在任务中调用 不能在中断中调用
* 参数：eID  二进制信号量ID   ticks 超时时间  =0 为永久等待
************************************************************************************************/
#if OSBYTES_OF_DELAYS > 0
OSBINSEM_EXT void OSWaitBinSem(OStypeInt8u eID,OStypeOfDelays ticks) ;
#else
OSBINSEM_EXT void OSWaitBinSem(OStypeInt8u eID) ;	
#endif

/************************************************************************************************
* 测试二进制信号量 并清零 不进行任务切换 可以在中断中调用
* 参数：eID  二进制信号量ID 
* 返回：二进制信号量状态
************************************************************************************************/
OSBINSEM_EXT OStypeInt8u OSTryBinSem(OStypeInt8u eID) ;

/************************************************************************************************
* 读取二进制信号量 不清零  可以在中断中调用
* 参数：eID  二进制信号量ID 
* 返回：二进制信号量状态
*************************************************************************************************/
OSBINSEM_EXT OStypeInt8u OSReadBinSem(OStypeInt8u eID) ;

/************************************************************************************************
* 发送二进制信号量公共代码  不含临界保护 不能直接调用
* 参数：eID  二进制信号量ID 
*************************************************************************************************/
OSBINSEM_EXT void OSSignalBinSem(OStypeInt8u eID) ;

/************************************************************************************************
* 在中断中发送二进制信号量  
* 参数：eID  二进制信号量ID 
*************************************************************************************************/
OSBINSEM_EXT void OSIntSignalBinSem(OStypeInt8u eID) ;

/*************************************************************************************************
* 在任务中发送二进制信号量  
* 参数：eID  二进制信号量ID 
**************************************************************************************************/
OSBINSEM_EXT void OSTaskSignalBinSem(OStypeInt8u eID) ;

/* 信号量 Sem  */
#ifdef __IN_OSSEM_C
#define OSSEM_EXT
#else
#define OSSEM_EXT extern
#endif

/* API  */
/*************************************************************************************************
* 初始化信号量  在OSStart() 前调用
* 参数：eID  信号量ID   value 初始值
**************************************************************************************************/
OSSEM_EXT void OSInitSem(OStypeInt8u eID,OStypeInt8u value) ;

/*************************************************************************************************
* 等待信号量  在任务中调用 不能在中断中调用
* 参数：eID  信号量ID   ticks 超时时间 =0 为永久等待
**************************************************************************************************/
#if OSBYTES_OF_DELAYS > 0
OSSEM_EXT void OSWaitSem(OStypeInt8u eID,OStypeOfDelays ticks) ;
#else
OSSEM_EXT void OSWaitSem(OStypeInt8u eID) ;	
#endif

/**************************************************************************************************
* 测试 信号量 并减1  可以在中断中调用
* 参数：eID  信号量ID 
* 返回：信号量状态
**************************************************************************************************/
OSSEM_EXT OStypeInt8u OSTrySem(OStypeInt8u eID) ;

/*************************************************************************************************
* 返回信号量数值 不清零  可以在中断中调用
* 参数：eID  信号量ID 
* 返回：信号量状态
***************************************************************************************************/
OSSEM_EXT OStypeInt8u OSReadSem(OStypeInt8u eID) ;

/**************************************************************************************************
* 发送信号量 公共代码 信号量最大值为255 超出最大值 发送操作被忽略 不含临界保护 不能直接调用
* 参数：eID 信号量ID 
***************************************************************************************************/
void OSSignalSem(OStypeInt8u eID) ;

/**************************************************************************************************
* 在中断中发送信号量  信号量最大值为255 超出最大值 发送操作被忽略
* 参数：eID  信号量ID 
***************************************************************************************************/
OSSEM_EXT void OSIntSignalSem(OStypeInt8u eID) ;

/**************************************************************************************************
* 在任务中发送信号量  信号量最大值为255 超出最大值 发送操作被忽略
* 参数：eID  信号量ID 
***************************************************************************************************/
OSSEM_EXT void OSTaskSignalSem(OStypeInt8u eID) ;

/* 事件标志 EFlag  */
#ifdef __IN_EFLAG_C
#define OSEFLAG_EXT
#else
#define OSEFLAG_EXT extern
#endif

/* API  */
/**************************************************************************************************
* 初始化事件标志 在OSStart()前调用
* 参数：eID  事件标志ID   value 初始值
***************************************************************************************************/
OSEFLAG_EXT void OSInitEFlag(OStypeInt8u eID,OStypeInt8u value) ;

/**************************************************************************************************
* 等待事件标志(掩码中的任意位)  在任务中调用 不能在中断中调用
* 参数：eID  事件标志ID  mask 掩码  ticks 超时时间  =0 为永久等待
***************************************************************************************************/
#if OSBYTES_OF_DELAYS > 0
OSEFLAG_EXT void OSWaitEFlagAny(OStypeInt8u eID,OStypeInt8u mask,OStypeOfDelays ticks) ;
#else
OSEFLAG_EXT void OSWaitEFlagAny(OStypeInt8u eID,OStypeInt8u mask) ; 	
#endif

/**************************************************************************************************
* 等待事件标志(掩码中的所有位)  在任务中调用 不能在中断中调用
* 参数：eID  事件标志ID  mask 掩码  ticks 超时时间  =0 为永久等待
***************************************************************************************************/
#if OSBYTES_OF_DELAYS > 0
OSEFLAG_EXT void OSWaitEFlagAll(OStypeInt8u eID,OStypeInt8u mask,OStypeOfDelays ticks) ;
#else
OSEFLAG_EXT void OSWaitEFlagAll(OStypeInt8u eID,OStypeInt8u mask) ;	
#endif

/**************************************************************************************************
* 等待事件标志(和掩码精确匹配)  在任务中调用 不能在中断中调用
* 参数：eID  事件标志ID  mask 掩码  ticks 超时时间  =0 为永久等待
**************************************************************************************************/
#if OSBYTES_OF_DELAYS > 0
OSEFLAG_EXT void OSWaitEFlagExact(OStypeInt8u eID,OStypeInt8u mask,OStypeOfDelays ticks) ; 
#else
OSEFLAG_EXT void OSWaitEFlagExact(OStypeInt8u eID,OStypeInt8u mask) ; 	
#endif

/**************************************************************************************************
* 读取事件标志值 不清零  可以在中断中调用
* 参数：eID  事件标志IDID 
* 返回：事件标志值
***************************************************************************************************/
OSEFLAG_EXT OStypeInt8u OSReadEFlag(OStypeInt8u eID) ;

/**************************************************************************************************
* 在中断中设置事件标志  
* 参数：eID 事件标志ID  mask 掩码
**************************************************************************************************/
OSEFLAG_EXT void OSIntSetEFlag(OStypeInt8u eID,OStypeInt8u mask) ;

/**************************************************************************************************
* 在任务中设置事件标志  
* 参数：eID  事件标志ID  mask 掩码 
***************************************************************************************************/
OSEFLAG_EXT void OSTaskSetEFlag(OStypeInt8u eID, OStypeInt8u mask) ;

/**************************************************************************************************
* 设置事件标志 公共代码  不含临界保护 不能直接调用 
* 参数：eID 事件标志ID  mask 掩码
***************************************************************************************************/
void OSSetEFlag(OStypeInt8u eID,OStypeInt8u mask)  ;

/**************************************************************************************************
* 在任务中清零事件标志 清零不会使任务就绪
* 参数：eID  事件标志ID  mask 掩码 
***************************************************************************************************/
OSEFLAG_EXT void OSClrEFlag(OStypeInt8u eID, OStypeInt8u mask) ;

/* 消息队列 MessageQ  */
#ifdef __IN_OSMSGQ_C
#define OSMSGQ_EXT
#else
#define OSMSGQ_EXT extern
#endif

/* API */
/***************************************************************************************************
* 初始化消息队列  在OSStart()前调用
* 参数：eID  消息队列ID   p 队列缓冲区指针 size 队列大小
****************************************************************************************************/
OSMSGQ_EXT void OSInitMsgQ(OStypeInt8u eID,OStypeInt8u OSLOC_MSGQ_BUF *p,OStypeInt8u size) ;

/***************************************************************************************************
* 等待消息队列  在任务中调用 不能在中断中调用
* 参数：eID  消息队列ID  msg 消息指针,用于接收消息,发生超时则消息指针指向的数据是不可预知的 
*       ticks 超时时间  =0 为永久等待
****************************************************************************************************/
#if OSBYTES_OF_DELAYS > 0
OSMSGQ_EXT void OSWaitMsgQ(OStypeInt8u eID,OStypeInt8u __idata *msg,OStypeOfDelays ticks) ;
#else
OSMSGQ_EXT void OSWaitMsgQ(OStypeInt8u eID,OStypeInt8u __idata *msg) ;	
#endif

/***************************************************************************************************
* 测试消息队列 消息出列  可以在中断中调用
* 参数：eID  消息队列ID  msg 消息指针
* 返回：0-操作失败  1-操作成功
****************************************************************************************************/
OSMSGQ_EXT OStypeInt8u OSTryMsgQ(OStypeInt8u eID,OStypeInt8u __idata *msg) ;

/***************************************************************************************************
* 读取消息队列 消息不出列  可以在中断中调用
* 参数：eID 消息队列ID  msg 消息指针
* 返回：0-操作失败  1-操作成功
***************************************************************************************************/
OSMSGQ_EXT OStypeInt8u OSReadMsgQ(OStypeInt8u eID,OStypeInt8u __idata *msg) ;

/**************************************************************************************************
* 在中断中发送消息到消息队列  
* 参数：eID 消息队列ID  msg 消息
* 返加：0-操作失败 1-操作成功
***************************************************************************************************/
OSMSGQ_EXT void OSIntSignalMsgQ(OStypeInt8u eID,OStypeInt8u msg) ;

/**************************************************************************************************
* 在任务中发送消息到消息队列  
* 参数：eID  消息队列ID  msg 消息
* 返加：0-操作失败 1-操作成功
***************************************************************************************************/
OSMSGQ_EXT void OSTaskSignalMsgQ(OStypeInt8u eID,OStypeInt8u msg) ;

/**************************************************************************************************
* 发送消息到消息队列 公共代码 不含临界保护 不能直接调有 
* 参数：eID 消息队列ID  msg 消息
***************************************************************************************************/
OSMSGQ_EXT void OSSignalMsgQ(OStypeInt8u eID,OStypeInt8u msg) ;

/**************************************************************************************************
* 返回队列消息个数  
* 参数：eID  消息队列ID 
* 返加：消息个数 
***************************************************************************************************/
OSMSGQ_EXT OStypeInt8u OSMsgQCount(OStypeInt8u eID) ;

/**************************************************************************************************
* 返回队列可用空间  
* 参数：eID  消息队列ID 
* 返加：可用空间个数 
***************************************************************************************************/
OSMSGQ_EXT OStypeInt8u OSMsgQEmpty(OStypeInt8u eID) ;

#endif 
